package com.artisan.controller;

import com.artisan.commons.AiJob;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.publisher.Sinks;
import reactor.core.scheduler.Schedulers;

@Slf4j
@RestController
public class MultiModelsController {

    @Resource
    ChatClient planningChatClient;

    @Resource
    ChatClient botChatClient;


    @GetMapping(value = "/streamOrigin", produces = "text/stream;charset=UTF8")
    Flux<String> streamOrigin(@RequestParam String message) {
        // 创建一个用于接收多条消息的
        Sinks.Many<String> sink = Sinks.many().unicast().onBackpressureBuffer();
        // 推送消息
        sink.tryEmitNext("正在计划任务...<br/>");


        new Thread(() -> {
            AiJob.Job job = planningChatClient.prompt().user(message)
                    .call().entity(AiJob.Job.class);

            switch (job.jobType()){
                case CANCEL ->{
                    System.out.println(job);
                    if(job.keyInfos().size()==0){
                        sink.tryEmitNext("请输入姓名和订单号.");
                    }
                    else {
                        // todo.. 执行业务  ticketService.cancel
                        // --->springai --->json
                        sink.tryEmitNext("退票成功!");
                    }
                }
                case QUERY -> {
                    System.out.println(job);
                    if(job.keyInfos().size()==0){
                        sink.tryEmitNext("请输入订单号.");
                    }
                    // todo.. 执行业务 ticketService.query()
                    sink.tryEmitNext("查询预定信息：xxxx");
                }
                case OTHER -> {
                    Flux<String> content = botChatClient.prompt().user(message).stream().content();
                    content.doOnNext(sink::tryEmitNext) // 推送每条AI流内容
                            .doOnComplete(() -> sink.tryEmitComplete())
                            .subscribe();
                }
                default -> {
                    System.out.println(job);
                    sink.tryEmitNext("解析失败");
                }
            }
        }).start();

        return sink.asFlux();
    }

    /**
     * 处理流式响应的HTTP GET请求，根据用户输入的消息执行不同的AI任务
     * 使用纯Reactor响应式编程方式
     *
     * @param message 用户输入的消息内容
     * @return 返回Flux流，包含处理过程中的实时消息推送
     */
    @GetMapping(value = "/stream", produces = "text/stream;charset=UTF8")
    Flux<String> stream(@RequestParam String message) {
        
        // 使用Reactor方式处理AI调用
        return Mono.fromCallable(() -> {
            // 调用AI模型解析用户意图并获取任务对象
            return planningChatClient.prompt().user(message)
                    .call()
                    .entity(AiJob.Job.class);
        })
        .subscribeOn(Schedulers.boundedElastic()) // 在弹性调度器上执行阻塞操作
        .flatMapMany(job -> {
            // 根据任务类型执行相应的业务逻辑
            switch (job.jobType()) {
                case CANCEL -> {
                    return handleCancelJobReactive(job);
                }
                case QUERY -> {
                    return handleQueryJobReactive(job);
                }
                case OTHER -> {
                    // 直接返回AI流式响应
                    return botChatClient.prompt().user(message).stream().content();
                }
                default -> {
                    log.warn("未知的任务类型: {}", job);
                    return Flux.just("解析失败");
                }
            }
        })
        .onErrorResume(e -> {
            log.error("处理AI任务时出现异常", e);
            return Flux.just("系统繁忙，请稍后再试。");
        })
        .startWith("hi, 正在计划任务...<br/>"); // 在流开始时推送初始消息
    }

    /**
     * 响应式处理退票任务
     */
    private Flux<String> handleCancelJobReactive(AiJob.Job job) {
        log.info("处理退票任务: {}", job);
        if (job.keyInfos().isEmpty()) {
            return Flux.just("请输入姓名和订单号.");
        } else {
            // todo.. 执行业务 ticketService.cancel
            return Flux.just("退票成功!");
        }
    }

    /**
     * 响应式处理查询任务
     */
    private Flux<String> handleQueryJobReactive(AiJob.Job job) {
        log.info("处理查询任务: {}", job);
        if (job.keyInfos().isEmpty()) {
            return Flux.just("请输入订单号.");
        }
        // todo.. 执行业务 ticketService.query()
        return Flux.just("查询预定信息：xxxx");
    }

    // 保留原有的方法用于streamOrigin
    private void handleCancelJob(AiJob.Job job, Sinks.Many<String> sink) {
        log.info("处理退票任务: {}", job);
        if (job.keyInfos().isEmpty()) {
            sink.tryEmitNext("请输入姓名和订单号.");
        } else {
            // todo.. 执行业务 ticketService.cancel
            sink.tryEmitNext("退票成功!");
        }
    }

    private void handleQueryJob(AiJob.Job job, Sinks.Many<String> sink) {
        log.info("处理查询任务: {}", job);
        if (job.keyInfos().isEmpty()) {
            sink.tryEmitNext("请输入订单号.");
        }
        // todo.. 执行业务 ticketService.query()
        sink.tryEmitNext("查询预定信息：xxxx");
    }

    private void handleOtherJob(String message, Sinks.Many<String> sink) {
        log.info("处理聊天任务");
        Flux<String> content = botChatClient.prompt().user(message).stream()
                .content();
        content
            .doOnNext(sink::tryEmitNext)
            .doOnComplete(sink::tryEmitComplete)
            .subscribe();
    }

}